package com.xnyzc.lhy.didi.service.impl.xiecheng;

import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.penum.cms.EVehicleType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.didi.common.constants.EXieChengVehicleType;
import com.xnyzc.lhy.didi.entity.price.CharterBillRules;
import com.xnyzc.lhy.didi.entity.price.CharterRulesParam;
import com.xnyzc.lhy.didi.entity.price.CharterSpecialRulesParam;
import com.xnyzc.lhy.didi.entity.price.OaSysCharterBillRuleMini;
import com.xnyzc.lhy.didi.service.xiecheng.CharteredPirceService;
import com.xnyzc.lhy.mis.entity.system.NewBillRules;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class CharteredPirceServiceImpl implements CharteredPirceService {
    @Autowired
    private RedisCommon redisCommon;

    @Override
    public List<HashMap<String, Object>> getPriceDetail(HashMap<Integer, List<NewBillRules>> ruleMap, List<Date> useTimes, HashMap<String, Integer> areaMap,
                                                        EVehicleType mvehicleType, BigDecimal centerPointDis, BigDecimal startEndDistance, Long cityCode) {
        long sl = System.currentTimeMillis();
        List<HashMap<String, Object>> rel = new ArrayList();
        HashMap<String, Object> localPriceMap = new HashMap<>();
        //根据车型获取当前线程的规则
        List<NewBillRules> rulesList = ruleMap.get(mvehicleType.getValue());
        if (rulesList == null || rulesList.size() == 0) {
            log.info("[{}]线程未匹配到对应规则数据", mvehicleType.getDesc());
            return new ArrayList<>();
        }
        for (int i = 0; i < rulesList.size(); i++) {

            NewBillRules newBillRules = rulesList.get(i);
            //判断禁运区域
            String areaMapKey = mvehicleType.getValue() + newBillRules.getRulesName();
            if (areaMap.containsKey(areaMapKey) &&
                    areaMap.get(areaMapKey) == 1) {
                continue;
            }
            String jsonRules = newBillRules.getJsonRules();
            OaSysCharterBillRuleMini mBillRule = null;
            OaSysCharterBillRuleMini aBillRule = null;
            CharterRulesParam charterRulesParam = JSONObject.parseObject(jsonRules, CharterRulesParam.class);
            CharterBillRules billRules = charterRulesParam.getBillRules();
            List<CharterSpecialRulesParam> specialDateRules = charterRulesParam.getSpecialDateRules();
            List<CharterSpecialRulesParam> specialTimeRules = charterRulesParam.getSpecialTimeRules();
            //套餐里程加价（起点或终点距离城市中心点）
            List<OaSysCharterBillRuleMini> mBillRules = billRules.getMBillRules();
            //套餐异地结束加价（起点与终点距离加价）
            List<OaSysCharterBillRuleMini> aBillRules = billRules.getABillRules();
            //总价
            BigDecimal totalFee = new BigDecimal(0);
            BigDecimal drawFee = new BigDecimal(0);
            Integer drawRatio = newBillRules.getDrawRatio();
            BigDecimal pointDistanceFee = new BigDecimal(0);
            BigDecimal startEndDistanceFee = new BigDecimal(0);
            BigDecimal days = new BigDecimal(useTimes.size());
            //保险费
            Double premium = CheckUtil.objIsEmpty(newBillRules.getPremium()) ? 0 : newBillRules.getPremium();
            //套餐价格
            BigDecimal comboPrice = new BigDecimal(billRules.getComboPrice());
            if (mBillRules != null && mBillRules.size() > 0) {
                for (OaSysCharterBillRuleMini rule : mBillRules) {
                    //1.大于等于分段起点；2.小于分段终点
                    if ((centerPointDis.compareTo(rule.getStartMileage()) == 1 || centerPointDis.compareTo(rule.getStartMileage()) == 0) && centerPointDis.compareTo(rule.getEndMileage()) == -1) {
                        mBillRule = rule;
                        break;
                    }
                }
            }
            if (aBillRules != null && aBillRules.size() > 0) {
                for (OaSysCharterBillRuleMini rule : aBillRules) {
                    //1.大于等于分段起点；2.小于分段终点
                    if ((startEndDistance.compareTo(rule.getStartMileage()) == 1 || startEndDistance.compareTo(rule.getStartMileage()) == 0) && startEndDistance.compareTo(rule.getEndMileage()) == -1) {
                        aBillRule = rule;
                        break;
                    }
                }
            }
            //计算距离中心点的价格
            if (mBillRule != null) {
                if (centerPointDis.doubleValue() - mBillRule.getStartingMileage().doubleValue() > 0) {
                    pointDistanceFee = pointDistanceFee.add(new BigDecimal(
                            (centerPointDis.doubleValue() - mBillRule.getStartingMileage().doubleValue()) * mBillRule.getMileageFee().doubleValue())).
                            add(mBillRule.getStartFee());
                }
            }
            //计算起点终点距离价格
            if (aBillRule != null ) {
                if (startEndDistance.doubleValue() - aBillRule.getStartingMileage().doubleValue() > 0) {
                    startEndDistanceFee = startEndDistanceFee.add(new BigDecimal(
                            (startEndDistance.doubleValue() - aBillRule.getStartingMileage().doubleValue()) * aBillRule.getMileageFee().doubleValue()))
                    .add(aBillRule.getStartFee());
                }
            }
            //3.算特殊时间段价格
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            //命中特殊时间加价值
            BigDecimal specialTimeFee = new BigDecimal(0);
            BigDecimal radioTime = new BigDecimal(0.00);
            try {
                Calendar startCalendar = Calendar.getInstance();
                //tripStartTime  乘客出发时间
                startCalendar.setTime(useTimes.get(0));
                int appointTime = startCalendar.get(Calendar.HOUR_OF_DAY) * 60 + startCalendar.get(Calendar.MINUTE);
                if (CheckUtil.objIsNotEmpty(specialTimeRules)) {
                    for (CharterSpecialRulesParam specialTimeRule : specialTimeRules) {
                        Calendar specialStartTime = Calendar.getInstance();
                        specialStartTime.setTime(sdf.parse(specialTimeRule.getTimeKey().split(",")[0]));
                        int specialStart = specialStartTime.get(Calendar.HOUR_OF_DAY) * 60 + specialStartTime.get(Calendar.MINUTE);
                        Calendar specialEndTime = Calendar.getInstance();
                        specialEndTime.setTime(sdf.parse(specialTimeRule.getTimeKey().split(",")[1]));
                        int specialEnd = specialEndTime.get(Calendar.HOUR_OF_DAY) * 60 + specialEndTime.get(Calendar.MINUTE);
                        if (appointTime >= specialStart && appointTime <= specialEnd) {
                            //加价值
                            specialTimeFee = totalFee.multiply(new BigDecimal(specialTimeRule.getTadio()).divide(new BigDecimal(100), BigDecimal.ROUND_HALF_UP));
                            //加价比例
                            radioTime = new BigDecimal(specialTimeRule.getTadio()).divide(new BigDecimal(100));
                            break;
                        }
                    }
                }
            } catch (
                    ParseException e) {
                e.printStackTrace();
            }
            //计算特殊日期加价
            BigDecimal radioDate = new BigDecimal(0.00);
            for (int j = 0; j < useTimes.size(); j++) {
                BigDecimal dayRadio = new BigDecimal(0);
                SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Long startTime = useTimes.get(j).getTime();
                try {
                    if (CheckUtil.objIsNotEmpty(specialDateRules)) {
                        for (CharterSpecialRulesParam specialDateRule : specialDateRules) {
                            Date specialStart = new Date();
                            Date specialEnd = new Date();
                            try {
                                specialStart = sdfDate.parse(specialDateRule.getTimeKey().split(",")[0]);
                                specialEnd = sdfDate.parse(specialDateRule.getTimeKey().split(",")[1]);
                            } catch (Exception e) {
                                log.error("开始或结束时间格式异常", e);
                            }
                            //判断是否在时间区间
                            if (startTime >= specialStart.getTime() && startTime < specialEnd.getTime()) {
                                //当日加价比例
                                dayRadio = new BigDecimal(specialDateRule.getTadio()).divide(new BigDecimal(100));
                                //总加价比例
                                radioDate = radioDate.add(dayRadio);
                                break;
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("处理特殊日期加价异常", e);
                }
                //计算当日价格
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                BigDecimal dayTotalFee = startEndDistanceFee.add(pointDistanceFee).add(new BigDecimal(premium)).add(comboPrice);
                dayTotalFee=dayTotalFee.add(dayTotalFee.multiply(radioTime)).add(dayTotalFee.multiply(dayRadio));
                dayTotalFee=dayTotalFee.setScale(2,BigDecimal.ROUND_UP).setScale(2, RoundingMode.HALF_UP);
                localPriceMap.put("dayTotalFee-" + sdf1.format(useTimes.get(j)), dayTotalFee);
                //加到总价上
                totalFee=totalFee.add(dayTotalFee);
            }
            BigDecimal r = new BigDecimal(drawRatio).divide(new BigDecimal(100));
            drawFee = totalFee.subtract(totalFee.multiply(r));
            int totalfee = totalFee.setScale(2, BigDecimal.ROUND_UP).setScale(2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).intValue();
            String priceMark = String.valueOf(IDUtil.nextId());
            HashMap<String, Object> resmap = new HashMap<>();
            resmap.put("packageCode", newBillRules.getRulesName());
            resmap.put("vendorVehicleType", EXieChengVehicleType.getByCType(mvehicleType.getValue()).getCode());
            resmap.put("priceMark", priceMark);
            resmap.put("price", totalfee);
            rel.add(resmap);
            localPriceMap.put("packageCode", newBillRules.getRulesName());
            localPriceMap.put("vendorVehicleType", EXieChengVehicleType.getByCType(mvehicleType.getValue()).getCode());
            localPriceMap.put("priceMark", String.valueOf(IDUtil.nextId()));
            localPriceMap.put("ruleId", newBillRules.getRuleId());
            localPriceMap.put("totalFee", totalFee);
            localPriceMap.put("drawFee", drawFee.setScale(2, BigDecimal.ROUND_UP).setScale(2, RoundingMode.HALF_UP));
            localPriceMap.put("startEndDistanceFee", startEndDistanceFee.setScale(2, BigDecimal.ROUND_UP).setScale(2, RoundingMode.HALF_UP));
            localPriceMap.put("pointDistanceFee", pointDistanceFee.setScale(2, BigDecimal.ROUND_UP).setScale(2, RoundingMode.HALF_UP));
            localPriceMap.put("premium", premium);
            localPriceMap.put("cityCode", cityCode);
            //两个小时有效期
            redisCommon.setHashMap(priceMark, localPriceMap, 60 * 60 * 2L);
        }
        log.info("线程[{}]计算完毕，共耗时{}毫秒", mvehicleType.getDesc(), System.currentTimeMillis() - sl);
        return rel;
    }

    public static void main(String[] args) {
        BigDecimal a = new BigDecimal(0);
        a = a.add(new BigDecimal(20));
        BigDecimal c = a.multiply(new BigDecimal(2));
        System.out.println(c);

    }

}
